/* -*-jde-*- */
package app.usuario;

import app.conexion.Conexion;
import app.conexion.ConexionException;
import app.util.SQLInjectionException;
import app.util.Validator;
import app.util.appException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Usuario Todo usuario del sistema
 *
 * @author Victor Miguel Peralta Santa Anna
 * @since Diciembre 2011
 * @version 0.1
 */
public class Usuario {

    /**
     * El identificador del usuario
     */
    private int nIdUsuario;
    /**
     * El usuario (cadena) asignado para ingresar al sistema
     */
    private String sUsuario;
    /**
     * La constraseña para ingresar al sistema
     */
    private String sContrasena;
    /**
     * La activación del usuario
     */
    private boolean bActivado;
    /**
     * El tipo de usuario que es, (Administrador, Alumno/Egresado, Empresa)
     */
    private String cTipoUsuario;

    /**
     * El principal agente del sistema es el usuario.
     *
     * @param nIdUsuario
     */
    public Usuario(int nIdUsuario, String sUsuario, String sContrasena,
            boolean bActivado, String cTipoUsuario) {
        this.nIdUsuario = nIdUsuario;
        this.sUsuario = sUsuario;
        this.sContrasena = sContrasena;
        this.bActivado = bActivado;
        this.cTipoUsuario = cTipoUsuario;
    }

    /**
     * Metodo que sirve para el login de un usuario dada su contrasena.
     *
     * @param username
     * @param contrasenia
     * @return
     */
    public static Usuario getUsuario(String username, String contrasenia) throws appException {
//        select * from usuarios where susuario like 'v1ctor' and scontrasena like 'contrasenia';

        try {
            Conexion con = new Conexion();
            String query = "select * from usuarios where susuario like '" + username
                    + "' and scontrasena like md5('" + contrasenia + "') ;";
            Usuario usuario = null;
            ResultSet r = con.exec(query);

            while (r.next()) {
                int idusuario = r.getInt("nidusuario");
                String susuario = r.getString("susuario");
                String scontrasena = r.getString("scontrasena");
                boolean activado = r.getBoolean("bactivado");
                String ctipousuario = r.getString("ctipousuario");
                usuario = new Usuario(idusuario, susuario, scontrasena, activado, ctipousuario);
            }

            con.close();
            return usuario;


        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("Usuario o contraseña inválidos");
        } catch (ConexionException ex) {
            System.err.println(ex);
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("Usuario o contraseña inválidos");
        }
    }

    /**
     * @return the nIdUsuario
     */
    public int getnIdUsuario() {
        return nIdUsuario;
    }

    /**
     * @return the sUsuario
     */
    public String getsUsuario() {
        return sUsuario;
    }

    /**
     * @return the sContrasena
     */
    public String getsContrasena() {
        return sContrasena;
    }

    /**
     * @return the bActivado
     */
    public boolean isbActivado() {
        return bActivado;
    }

    /**
     * @return the cTipoUsuario
     */
    public String getcTipoUsuario() {
        return cTipoUsuario;
    }

    /**
     * @param sContrasena the sContrasena to set
     */
    public void setsContrasena(String sContrasena) {
        this.sContrasena = sContrasena;
    }

    /**
     * @param bActivado the bActivado to set
     */
    public void setbActivado(boolean bActivado) {
        this.bActivado = bActivado;
    }

    /**
     * Nos dice si un usuario esta disponible en la base de datos
     *
     * @param usuario el nombre del usuario
     * @return verdadero si el usuario esta disponible falso en otro caso.
     */
    public static boolean isDisponible(String usuario) throws appException {
        try {
            Conexion con = new Conexion();
            String query = "select isUsuario('" + usuario + "');";
            ResultSet r = con.exec(query);

            r.next();
            boolean b = !r.getBoolean("isUsuario");
            con.close();

            return b;
        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo verificar la existencia del usuario.");
        } catch (ConexionException ex) {
            System.err.println(ex);
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pudo verificar la existencia del usuario.");
        }
    }

    /**
     * Guarda el objeto en la base de datos independientemente si éste es nuevo
     * o no.
     */
    public void save() throws appException {

        try {

            String activacion = cTipoUsuario.equals("M") ? "TRUE" : "FALSE";
            Conexion con = new Conexion();
            String query = "select ";
            if (nIdUsuario == -1) {
                query += "addUsuario('" + sUsuario + "'";
                query += ", '" + sContrasena + "'," + activacion + ", '" + cTipoUsuario + "');";

                if (!Validator.checkSQLInjection(query)) {
                    ResultSet r = con.exec(query);
                    while (r.next()) {
                        int resultado = r.getInt("addusuario");
                        this.nIdUsuario = resultado;
                    }
                }

            } else {
                query += "updateUsuario(" + nIdUsuario;
                query += ", '" + sContrasena + "');";

                con.exec(query);
            }

            con.close();

        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo guardar el elemento: Usuario");
        } catch (SQLException sqle) {
            System.err.println(sqle);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqle);
            throw new appException("No se pudo guardar el elemento: Usuario");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Borra el objeto de la base de datos.
     */
    public void delete() throws appException {
        try {
            Conexion con = new Conexion();
            String query = "select deleteUsuario( " + nIdUsuario + " );";
            con.exec(query);

            con.close();
        } catch (ConexionException ce) {
            System.err.println(ce);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ce);
            throw new appException("No se pudo borrar el elemento: Usuario");
        }
    }

    /**
     * Conexiones de prueba a la base de datos
     *
     * @param args
     * @throws ConexionException
     * @throws SQLException
     * @throws appException
     */
    public static void main(String args[]) throws ConexionException, SQLException, appException {


        //nuevo
        Usuario u = new Usuario(-1, "nuevo mil ochimil", "contrasenia", false, "a");
        u.save();
        // existente
        //Usuario u = new Usuario(2, "nuevo usuario", "washa washa", false, 'a');
        //tc.setsTipocontratacion("a");
        //u.save();

        //u.delete();

        //System.out.println(u.toString());

        boolean b = isDisponible("nuevo");
        System.out.println(b);

        Usuario existente = Usuario.getUsuario("nuevo", "contrasenia");
        System.out.println(existente);



    }

    @Override
    public String toString() {
        return "Usuario{" + "nIdUsuario=" + nIdUsuario + ", sUsuario=" + sUsuario + ", sContrasena=" + sContrasena + ", bActivado=" + bActivado + ", cTipoUsuario=" + cTipoUsuario + '}';
    }
}
